package com.zwj.myinterface.controller;

import cn.hutool.core.date.ChineseDate;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.lang.UUID;
import com.zwj.myinterface.model.entity.EnglishSentence;
import com.zwj.myinterface.model.entity.UnfashionableLoveTalk;
import com.zwj.myinterface.model.req.*;
import com.zwj.myinterface.model.resp.*;
import com.zwj.myinterface.service.EnglishSentenceService;
import com.zwj.myinterface.service.UnfashionableLoveTalkService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.time.LocalDate;
import java.util.Date;
import java.util.Objects;
import java.util.Random;

@RestController
@RequiredArgsConstructor
public class OpenApiController {

    private static final String REFERENCE_QQ_NUMBER = "2308850421";
    private final EnglishSentenceService englishSentenceService;
    private final UnfashionableLoveTalkService unfashionableLoveTalkService;

    @GetMapping("/daily-english-sentence")
    public EnglishSentenceResp getDailyEnglishSentence() {
        // 调用获取每日英语范句的逻辑，从数据库或其他数据源中获取当日的经典英语范句数据
        long count = englishSentenceService.count();
        long id = new Random().nextInt((int) count + 1);
        EnglishSentence englishSentence = englishSentenceService.getById(id);
        if (Objects.isNull(englishSentence)) {
            return EnglishSentenceResp.builder().sentence("Welcome to RuoChu API Open Platform").build();
        }
        return EnglishSentenceResp.builder().sentence(englishSentence.getSentence()).build();
    }

    @PostMapping("/bmi")
    public BMIResp calculateBMI(@RequestBody BMIReq request) {
        double height = request.getHeight();
        double weight = request.getWeight();
        int gender = request.getGender();
        // 计算BMI指数
        double bmi = weight / (height * height);
        // 判断身体状况级别
        String level;
        if (bmi < 18.5) {
            level = "偏瘦";
        } else if (bmi < 24) {
            level = "正常";
        } else if (bmi < 28) {
            level = "超重";
        } else {
            level = "肥胖";
        }
        // 判断是否达到健康标准
        boolean isHealthy =
                (gender == 0 && bmi >= 18.5 && bmi <= 24)
                        || (gender == 1 && bmi >= 18.5 && bmi <= 23.9);
        return new BMIResp(bmi, level, isHealthy);
    }

    @PostMapping("/predict-height")
    public PredictedHeightResp predictHeight(@RequestBody PredictedHeightReq request) {
        double fatherHeight = request.getFatherHeight();
        double motherHeight = request.getMotherHeight();
        int gender = request.getGender();
        // 根据性别和父母身高预测子女的成年身高，这里只是简单的示例计算，实际可采用更精确的算法
        double predictedHeight = (fatherHeight + motherHeight) / 2 + (gender == 0 ? 6.5 : -6.5);
        return new PredictedHeightResp(predictedHeight);
    }

    @PostMapping("/qq-fortune")
    public QQFortuneResp calculateQQFortune(@RequestBody QQFortuneReq request) {
        String qqNumber = request.getQqNumber();
        // 在这里进行QQ号码吉凶预测的业务逻辑处理，可以使用算法或规则来判断吉凶
        // 判断QQ号码位数是否是偶数
        boolean isEvenLength = qqNumber.length() % 2 == 0;
        // 判断前5位数是否大于55555
        boolean isGreater = qqNumber.length() >= 5 && Integer.parseInt(qqNumber.substring(0, 5)) > 55555;
        // 判断后几位数是否小于100
        boolean isLess = qqNumber.length() >= 3 && Integer.parseInt(qqNumber.substring(qqNumber.length() - 3)) < 100;
        // 判断是否含有2个1或者含有1个6
        boolean hasTwoOnes = qqNumber.contains("1") && qqNumber.indexOf("1") != qqNumber.lastIndexOf("1");
        boolean hasOneSix = qqNumber.contains("6");
        // 计算编辑距离
        int distance = calculateEditDistance(qqNumber);
        // 计算匹配度
        double similarity = calculateSimilarity(qqNumber.length(), distance);
        // 判断匹配度是否达到阈值
        boolean isGoodSimilarity = similarity >= 0.6;
        // 假设根据某种规则判断吉凶
        boolean isGoodFortune = (
                (isEvenLength && isGreater && isLess)
                        || (hasTwoOnes || hasOneSix)
        ) || isGoodSimilarity;
        return new QQFortuneResp(qqNumber, isGoodFortune);
    }

    // 计算编辑距离
    private int calculateEditDistance(String s1) {
        int m = s1.length();
        int n = OpenApiController.REFERENCE_QQ_NUMBER.length();
        int[][] dp = new int[m + 1][n + 1];
        for (int i = 0; i <= m; i++) {
            dp[i][0] = i;
        }
        for (int j = 0; j <= n; j++) {
            dp[0][j] = j;
        }
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                if (s1.charAt(i - 1) == OpenApiController.REFERENCE_QQ_NUMBER.charAt(j - 1)) {
                    dp[i][j] = dp[i - 1][j - 1];
                } else {
                    int replace = dp[i - 1][j - 1] + 1;
                    int insert = dp[i][j - 1] + 1;
                    int delete = dp[i - 1][j] + 1;
                    dp[i][j] = Math.min(replace, Math.min(insert, delete));
                }
            }
        }
        return dp[m][n];
    }

    // 计算匹配度
    private double calculateSimilarity(int length, int distance) {
        return 1 - (double) distance / length;
    }

    @PostMapping("/birth-assistant")
    public BirthAssistantResp calculateBirthInfo(@RequestBody BirthAssistantReq request) {
        int year = request.getYear();
        int month = request.getMonth();
        int day = request.getDay();
        // 根据年月日时获取生辰八字信息
        String eightCharacters = calculateEightCharacters(year, month, day);
        // 查询其他生辰信息
        String constellation = calculateConstellation(month, day);
        String zodiac = calculateZodiac(year);
        return new BirthAssistantResp(eightCharacters, constellation, zodiac);
    }

    // 计算生辰八字
    private String calculateEightCharacters(int year, int month, int day) {
        // 创建一个Date实例表示公历日期
        LocalDate date = LocalDate.of(year, month, day);
        // 使用ChineseDate.from方法将公历日期转换为农历日期
        ChineseDate chineseDate = new ChineseDate(date);
        int chineseYear = chineseDate.getChineseYear();
        String[] heavenlyStems = {"甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸"};
        String[] earthlyBranches = {"子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"};
        int heavenlyStemIndex = (chineseYear - 4) % 10;
        int earthlyBranchIndex = (chineseYear - 4) % 12;
        String heavenlyStem = heavenlyStems[heavenlyStemIndex];
        String earthlyBranch = earthlyBranches[earthlyBranchIndex];
        return heavenlyStem + earthlyBranch;
    }

    // 计算星座
    private String calculateConstellation(int month, int day) {
        String[] constellations = {
                "水瓶座", "双鱼座", "白羊座", "金牛座", "双子座", "巨蟹座",
                "狮子座", "处女座", "天秤座", "天蝎座", "射手座", "摩羯座"
        };
        int[] constellationEndDays = {20, 19, 21, 20, 21, 22, 23, 23, 23, 22, 21, 20};
        int index = month - 1;
        if (day > constellationEndDays[index]) {
            index = (index + 1) % 12;
        }
        return constellations[index];
    }

    // 计算生肖
    private String calculateZodiac(int year) {
        String[] zodiacs = {
                "鼠", "牛", "虎", "兔", "龙", "蛇",
                "马", "羊", "猴", "鸡", "狗", "猪"
        };
        int startYear = 1900; // 开始的年份，根据具体需求进行修改
        int index = (year - startYear) % 12;
        if (index < 0) {
            index += 12;
        }
        return zodiacs[index];
    }

    // 人民币转美元
    @PostMapping("/convertCurrency")
    public ConversionResp convertCurrency(@RequestBody ConversionReq request) {
        double amount = request.getAmount();
        double exchangeRate = 0.15; // 汇率：1 CNY = 0.15 USD
        double convertedAmount = amount * exchangeRate;
        return new ConversionResp(convertedAmount);
    }

    // 获得随机头像
    @GetMapping(value = "/avatar", produces = MediaType.IMAGE_PNG_VALUE)
    public byte[] generateAvatar() throws IOException {
        // 生成一个 200x200 大小的头像
        BufferedImage avatar = generateAvatar(200);
        // 将头像转换为字节数组
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ImageIO.write(avatar, "png", outputStream);
        return outputStream.toByteArray();
    }

    public BufferedImage generateAvatar(int size) {
        BufferedImage avatar = new BufferedImage(size, size, BufferedImage.TYPE_INT_RGB);
        Graphics graphics = avatar.getGraphics();
        Random random = new Random();
        // 绘制背景颜色
        Color backgroundColor = new Color(random.nextInt(256), random.nextInt(256), random.nextInt(256));
        graphics.setColor(backgroundColor);
        graphics.fillRect(0, 0, size, size);
        // 绘制随机图形
        Color shapeColor = new Color(random.nextInt(256), random.nextInt(256), random.nextInt(256));
        graphics.setColor(shapeColor);
        int shapeSize = size / 2;
        int shapeX = (size - shapeSize) / 2;
        int shapeY = (size - shapeSize) / 2;
        graphics.fillOval(shapeX, shapeY, shapeSize, shapeSize);
        // 绘制随机文本
        String text = generateRandomText();
        graphics.setColor(Color.WHITE);
        graphics.drawString(text, size / 4, size / 2);
        graphics.dispose();
        return avatar;
    }

    private String generateRandomText() {
        return UUID.randomUUID().toString();
    }

    @GetMapping("/unfashionable-love-talk")
    public UnfashionableLoveTalkResp getUnfashionableLoveTalk() {
        // 调用获取每日英语范句的逻辑，从数据库或其他数据源中获取当日的经典英语范句数据
        long count = unfashionableLoveTalkService.count();
        long id = new Random().nextInt((int) count + 1);
        UnfashionableLoveTalk unfashionableLoveTalk = unfashionableLoveTalkService.getById(id);
        if (Objects.isNull(unfashionableLoveTalk)) {
            return UnfashionableLoveTalkResp.builder().loveTalk("欢迎来到若初API开放平台").build();
        }
        return UnfashionableLoveTalkResp.builder().loveTalk(unfashionableLoveTalk.getLoveTalk()).build();
    }
}
